package ru.amse.ilyin.diagram.impl;

import java.awt.Point;
import java.util.HashSet;
import java.util.Set;

import ru.amse.ilyin.diagram.Diagram;
import ru.amse.ilyin.diagram.Element;
import ru.amse.ilyin.diagram.Link;
import ru.amse.ilyin.diagram.Renderer;

/**
 * Implementation of {@link Diagram} interface.
 *
 * @author Alexander Ilyin
 */
public class DiagramImpl implements Diagram {
	private final Set<AbstractElement> elements = new HashSet<AbstractElement>();
	
	private final Set<Link> links = new HashSet<Link>();

	/**
	 * Adds a specified element to the diagram.
	 * 
	 * @param element element to be added
	 */
	public void addElement(AbstractElement element) {
		elements.add(element);
	}

	/**
	 * Adds a specified link to the diagram.
	 * 
	 * @param link link to be added
	 */
	public void addLink(LinkImpl link) {
		if (!elements.contains(link.getFirstElement()) ||
			!elements.contains(link.getSecondElement())) {
			throw new IllegalArgumentException("elements are not in the diagram");
		}
		
		links.add(link);
	}

	public void draw(Renderer renderer) {
		layout();
	
		for (Element vertexPresentation : elements) {
			vertexPresentation.draw(renderer);
		}
		for (Link edgePresentation : links) {
			edgePresentation.draw(renderer);
		}
	}

	private void layout() {
		final Point center = new Point(200, 150);
		final int radius = 100;
		final int n = elements.size();
		int i = 0;
		for (AbstractElement element : elements) {
			element.setLocation(new Point(
					center.x + (int) (radius * Math.sin(2 * Math.PI * i / n)),
					center.y + (int) (radius * Math.cos(2 * Math.PI * i / n))
			));
			i++;
		}
	}

}
